<!-- <template>
  <div class="d-more-wrap" ref="moreWrap" :style="computedStyle">
    <div class="content" ref="content">
      <slot></slot>
    </div>
    <el-popover placement="bottom" trigger="click" v-show="isOverFlow">
      <div slot="reference" v-show="isOverFlow" class="more" ref="more">...</div>
      <popover>
        111
      </popover>
    </el-popover>
  </div>
</template> -->

<script lang="jsx">
const map = new WeakMap() //优化点，垃圾回收
const ob = new ResizeObserver((entries) => {
  for (const entry of entries) {
    const hander = map.get(entry.target)
    if (hander) {
      hander({
        width: entry.borderBoxSize[0].inlineSize,
        height: entry.borderBoxSize[0].blockSize
      })
    }
  }
})
export default {
  props: {
    width: {
      type: String,
      default: '100%'
    }
  },
  directives: {
    sizeOb: {
      //构建局部指令，监控元素变化
      bind(el, binding) {
        //监听el元素尺寸的变化
        map.set(el, binding.value)
        ob.observe(el)
      },
      unbind(el) {
        ob.unobserve(el)
        map.delete(el) // 清理 map
      }
    }
  },
  data() {
    return {
      isOverFlow: false,
      hiddenSlot: []
    }
  },
  computed: {
    computedStyle() {
      return {
        width: this.width
      }
    }
  },
  methods: {
    //判断是否溢出，溢出则显示更多按钮
    handleOverflow() {
      const content = this.$refs.content
      if (content.scrollWidth > content.clientWidth) {
        this.isOverFlow = true
      } else {
        this.isOverFlow = false
      }
    },
    //计算出插槽可容纳的可见数量
    getVisibleCount() {
      const content = this.$refs.content
      const contentWidth = content.offsetWidth
      const children = content.children
      let sum = 0
      for (let i = 0; i < children.length; i++) {
        sum += children[i].offsetWidth
        if (sum > contentWidth) {
          return i - 2
        }
      }
      return children.length
    },
    handleSlot() {
      //获取插槽总数
      const count = this.$slots.default.length
      //获取可见数量
      const visibleNum = this.getVisibleCount()
      //获取不可见的数量
      const hiddenNum = count - visibleNum
      //获取不可见的插槽
      const hiddenSlot = this.$slots.default.slice(visibleNum)
      this.hiddenSlot = hiddenSlot
      //移除不可见的插槽
      this.$slots.default.splice(visibleNum)
    },
    handleSizeChange({ width }) {
      console.log('🚀 ~ handleSizeChange ~ width:', width)
      //   this.handleSlot()
    }
  },
  render() {
    return (
      <div
        class="d-more-wrap"
        ref="moreWrap"
        style={this.computedStyle}
        v-size-ob={this.handleSizeChange}
      >
        <div class="content" ref="content">
          {this.$slots.default}
        </div>
        <el-popover
          popper-class="d-more-popover"
          placement="bottom"
          trigger="click"
          v-show={this.isOverFlow}
        >
          <el-button
            icon="el-icon-more"
            slot="reference"
            size="small"
            class="more"
            ref="more"
          ></el-button>
          <div class="hidden-slot">{this.hiddenSlot}</div>
        </el-popover>
      </div>
    )
  },
  mounted() {
    this.$nextTick(() => {
      console.log('mounted')
      this.handleOverflow()
      if (this.isOverFlow) {
        this.handleSlot()
      }
    })
  }
}
</script>

<style lang="scss" scoped>
.d-more-wrap {
  display: inline-flex;
  .content {
    display: flex;
    flex-wrap: nowrap;
    overflow: hidden;
  }
  .more {
    margin-left: 10px;
    opacity: 0.5;
  }
}
</style>
<style lang="scss">
.d-more-popover {
  min-width: fit-content !important;
  .hidden-slot {
    display: inline-flex;
    flex-direction: column;
    gap: 12px;
    .el-button + .el-button {
      margin: 0 !important;
    }
  }
}
</style>
